package com.browsesoft.user;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.browsesoft.EntityManager;
import com.browsesoft.ManagerGroup;
import com.browsesoft.Tools;
import com.browsesoft.dbtools.BSConnection;
import com.browsesoft.dbtools.DBTools;
import com.browsesoft.doaction.DoActionHelper;
import com.browsesoft.log.LogHelper;
import com.browsesoft.oa.CssStyle;
import com.browsesoft.oa.EncryptMachine;
import com.browsesoft.oa.GetEncryptMachineTool;
import com.browsesoft.resource.BasicResource;
import com.browsesoft.resource.Resource;
import com.browsesoft.resource.ResourceTool;
import com.browsesoft.resource.Right;
import org.json.JSONObject;

/**
 * 用户
 */
public class User extends BasicResource {

	private static final long serialVersionUID = -2137008676489083870L;

	// 权限中所有的资源列表
	private transient LinkedList functions = new LinkedList();

	/**
	 * 动作处理参数
	 */
	private String doAction = null;

	/**
	 * 用户风格
	 */
	private CssStyle style;

	/**
	 * 用户是否要有提示信息
	 */
	private boolean tip;

	/**
	 * 用户可以设的tip间隔多少时间出来一次
	 */
	private int timetip;

	/**
	 * 用户角色
	 */
	private LinkedList roles = new LinkedList();

	/**
	 * 用户的登陆次数
	 */
	private int loginNumber = 0;

	/**
	 * 当前请求
	 */
	private HttpServletRequest currentRequest = null;

	/**
	 * 空构造
	 */
	public User() {
		super();
		this.attributes.put("deleted", "false");
		this.attributes.put("resourcetype", "user");
	}

	/**
	 * 设置用户风格
	 */
	public void setCssStyle(CssStyle style) {
		this.style = style;
		this.attributes.put("styleid", style.getID());
	}

	/**
	 * 得到用户风格
	 */
	public CssStyle getCssStyle() {
		return this.style;
	}

	public void createRelation() {
		super.createRelation();
		String styleid = (String) this.attributes.get("styleid");
		this.style = (CssStyle) EntityManager.getInstance().getObject(styleid);
		// 初始化设置角色
		this.initRoles();
	}

	/**
	 * 初始华设置用户
	 */
	private void initRoles() {
		// 根据角色id列表添加角色
		String roleIds = (String) this.getAttributes().get("roles");
		LinkedList temp = Tools.stringToLinkedList(roleIds);
		Iterator iter = temp.iterator();
		while (iter.hasNext()) {
			String roleId = (String) iter.next();
			Object obj = EntityManager.getInstance().getObject(roleId);
			if (obj != null) {
				this.roles.add((Role) obj);
			}
		}
	}

	/**
	 * 得到用户类型
	 */
	public String getType() {
		// 取出可用标志
		String sign = (String) this.getAttributes().get("using");
		// 如果不可用
		if (sign != null && sign.equals("否")) {
			return "lockuser";
		}
		// 取出外出标志
		String user = (String) this.getAttributes().get("outuser");
		// 如果外出
		if (user != null && user.equals("是")) {
			return "outuser";
		} else {
			return "user";
		}
	}

	/**
	 * 初始化model
	 */
	public void init(HttpServletRequest request) throws Exception {
		super.init(request);
		this.templateName = request.getParameter("templatename");
		this.setTemplateName(templateName);
		String id = request.getParameter("point");
		if (id != null && !id.equals("")) {
			this.attributes = ((Resource) EntityManager.getInstance()
					.getObject(id)).getAttributes();
		}
	}

	/**
	 * 使用属性构造
	 */
	public User(Hashtable attrs) {
		super(attrs);
		this.setLoginNumber(attrs);
	}

	/**
	 * 根据用户中文名称得到与该用户同部门的用户
	 * @return User
	 */
	public User getUserFromCName(String name) {
		Iterator v = this.getParent().getChildren();
		while (v.hasNext()) {
			Resource res = (Resource) v.next();
			if (res.getType().equals("user")) {
				String cname = (String) res.getAttributes().get("name");
				if (cname.equals(name)) {
					return (User) res;
				}
			}
		}
		return null;
	}

	/**
	 * 根据属性设置登陆次数
	 * 
	 * @param attrs
	 *            属性表
	 */
	public void setLoginNumber(Hashtable attrs) {
		try {
			// 从属性中得到登陆次数
			String num = (String) attrs.get("loginnumber");
			// 设置登陆次数
			this.loginNumber = Integer.parseInt(num);
		} catch (Exception e) {
			this.loginNumber = 0;
		}
	}

	/**
	 * 设置用户属性
	 */
	public void updateAttributes(Hashtable attrs) throws Exception {
		// 添加初始属性
		super.updateAttributes(attrs);
		// 如果有动作处理
		if (doAction != null && !doAction.equals("")) {
			DoActionHelper.doAction(this.getComponent(), this.doAction,
					this.currentRequest, this);
		}
		// 如果应该插入
		if (isShouldInsert()) {
			this.getParent().update();
			parentID = null;
		}
	}

	// 添加
	public void insert() throws Exception {
		super.insert();
		// 向点聚控件使用表中插入记录
		//insertToAipUserTable();
		// 记录日志
		LogHelper.logEntity(this.loginUser, "用户维护", "添加用户" + this.getName());
	}

	/**
	 * 给点聚控件使用的表中插入记录
	 */
	private void insertToAipUserTable() {
		// 向aip_user表中插入记录
		String CUSERID = (String) this.getAttributes().get("id");
		String cUserName = (String) this.getAttributes().get("name");
		String sql = "INSERT INTO aip_user VALUES ('"
				+ CUSERID
				+ "', '"
				+ cUserName
				+ "', '', '', 0, 0, '934;535800;1<;:8?96:5=72?72?1611', '测试用户', 1120201991, 0,0, 'admin')";
		this.executeSql(sql);
	}

	/**
	 * 根据用户得到同一部门下的所有用户
	 * @return User
	 */
	public LinkedList getSameDepUsers() {
		LinkedList user = new LinkedList();
		Iterator list = parent.getChildren();
		while (list.hasNext()) {
			Resource res = (Resource) list.next();
			if (res.getType().equals("user")) {
				user.add(res);
			}
		}
		return user;
	}

	/**
	 * 得到用户的所有功能列表
	 */
	public void loadFunctions() {
		this.functions.clear();
		for (int i = 0; i < rights.size(); i++) {
			Resource res = (Resource) ((Right) rights.get(i)).getResource();
			if (res != null && res.getType().equals("function")) {
				functions.add(res);
			}
		}
		for (int i = 0; i < functions.size(); i++) {
			Function func = (Function) functions.get(i);
			// 将该叶子功能的所有父功能添加到列表中
			// while (func != null &&
			// func.getType().getType().equals("function"))
			while (func != null) {
				if (!functions.contains(func)) {
					functions.add(func);
				}
				func = (Function) func.getParent();
			}
		}
	}

	/**
	 * 根据用户所拥有的所有功能列表得到根功能列表
	 */
	public LinkedList getRootFunctions() {
		this.loadFunctions();
		// 得到根功能
		LinkedList roots = getChildFunctions(null);
		// 有根功能，得到根功能的所有子功能
		if (roots.size() != 0) {
			return getChildFunctions((Function) roots.get(0));
		}
		// 没有根功能，返回空
		else {
			return new LinkedList();
		}
	}

	/**
	 * 从用户所拥有的功能列表中取得某功能的所有子功能
	 */
	public LinkedList getChildFunctions(Function func) {
		LinkedList result = new LinkedList();
		for (int i = 0; i < functions.size(); i++) {
			Function function = (Function) functions.get(i);
			if (function.getParent() == func) {
				result.add(function);
			}
		}
		Function.sort(result);
		return result;
	}

	/**
	 * 生成菜单
	 * 
	 * @return 菜单的html字串
	 */
	// public String createMenu() {
	// String str = "";
	// // 装入该用户的所有功能
	// loadFunctions();
	// // 得到根功能
	// LinkedList root = getRootFunctions();
	// // 菜单头
	// str += "<TABLE cellSpacing=1 id=menu onclick='menuClick()'
	// onmouseout='menuOut()'"
	// + "onmouseover='menuOver()' onselectstart='return false'><TBODY><TR
	// id=menubar>";
	// for (int i = 0; i < root.size(); i++) {
	// // 根元素菜单
	// Function r = (Function) root.get(i);
	// str += "<TD class=root noWrap>\n"
	// + r.getAttributes().get("name")
	// + "<TABLE cellSpacing=0 class=menu style='VISIBILITY: hidden'><TBODY>\n";
	// LinkedList v = getChildFunctions(r);
	// // 生成子元素菜单
	// for (int j = 0; j < v.size(); j++) {
	// Function child = (Function) v.get(j);
	// str += createHTML(child);
	// }
	// str += "\n</tbody></table></td>";
	// }
	// str += "\n<TD class=disabled width='100%'></TD></tr></tbody></table>";
	// return str;
	// }
	/**
	 * 生成菜单
	 * 
	 * @param function
	 *            子功能
	 * @return html字串
	 */
	// public String createHTML(Function function) {
	// String str = "";
	// if (getChildFunctions(function).size() == 0) {
	// str += "<TR href='#' onclick=\"window.open('"
	// + function.getAttributes().get("link") + "')\""
	// + ">\n<TD noWrap>" + function.getAttributes().get("name")
	// + "</TD><TD></TD></TR>";
	// } else {
	// str += "<TR class=sub><TD noWrap>"
	// + (String) function.getAttributes().get("name")
	// + "</TD><TD><SPAN class=more>4</SPAN>\n"
	// + "<TABLE cellSpacing=0 class=menu style='VISIBILITY: hidden'><TBODY>";
	// for (int i = 0; i < function.getFunctions().size(); i++) {
	// Function child = (Function) getChildFunctions(function).get(i);
	// str += createHTML(child);
	// }
	// str += "\n</tbody></table></td></tr>";
	// }
	// return str;
	// }
	/**
	 * 记录客户端环境
	 * 
	 * @param request
	 */
	public void service(HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		super.service(request, response);
		this.doAction = request.getParameter("doaction");
		this.currentRequest = request;
		if (parentID == null) {
			parentID = request.getParameter("parentid");
		}
		// 如果插入，初始化默认值
		if (this.isShouldInsert()) {
			initAttrs();
		}
	}

	/**
	 * 初始化密码等属性
	 */
	private void initAttrs() {
		// 角色处理
		this.getAttributes().put("roles", this.getRolesIds());
		// 放入图标
		this.attributes.put("f_icon", "tree_user");
		// 得到默认密码
		String pass = this.getPass();
		// 加入
		this.attributes.put("password", pass);
	}

	/**
	 * 用户修改自已的密码
	 * 
	 * @param oldPassword
	 * @param newPassword
	 * @param affirmPassword
	 * @throws Exception
	 */
	public void modifyPassword(String oldPassword, String newPassword,
			String affirmPassword) throws Exception {
		// 如果输入旧密码正确则开始修改密码
		if (this.getAttributes().get("password").equals(oldPassword)) {
			// 如果输入密码确认成功则修改密码
			if (newPassword.equals(affirmPassword)) {
				attributes.remove("password");
				attributes.put("password", newPassword);
				// 向数据库存储
				this.update();
			}
		}
	}

	// 修改双密码的第二个密码
	public void modifyPassword2(String oldPassword, String newPassword,
			String affirmPassword) throws Exception {
		// 如果输入旧密码正确则开始修改密码
		if (this.getAttributes().get("password2").equals(oldPassword)) {
			// 如果输入密码确认成功则修改密码
			if (newPassword.equals(affirmPassword)) {
				attributes.remove("password2");
				attributes.put("password2", newPassword);
				// 向数据库存储
				this.update();
			}
		}
	}

	public void setIsTip(boolean temp) {
		this.tip = temp;
	}

	public boolean getIsTip() {
		return this.tip;
	}

	public void setTiptime(int t) {
		this.timetip = t;
	}

	public int getTipTime() {
		return timetip;
	}

	// 判断新增人是否有相同的登陆名
	public boolean isSame(String ename) throws Exception {
		EntityManager entitymanager = (EntityManager) ManagerGroup
				.getManagerGroup().getManager("entity");
		Hashtable ht = new Hashtable();
		ht.put("ename", ename);
		LinkedList list = entitymanager.getObjects("com.browsesoft.user.User",
				ht);
		// 如果没找到
		if (list.size() == 0) {
			return false;
		}
		// 否则，找到一个
		else if (list.size() == 1) {
			// 看是否与自己相同
			return list.get(0) != this;
		}
		// 否则，找到多个
		else {
			return true;
		}
	}

	/**
	 * 得到用户角色
	 * 
	 * @return 角色列表
	 */
	public LinkedList getRoles() {
		return this.roles;
	}
	
	
	/**
	 * 得到角色字符串连接，','号分割
	 * @return
	 */
	public String getRolesStr()
	{
		String result ="";
	    Iterator iter = this.roles.iterator();
	    while(iter.hasNext())
	    {
	    	Role role = (Role) iter.next();
	        result+= (String) role.attributes.get("name") +",";
	    }
	    if(result.endsWith(","))
	    {
	    	result = result.substring(0,result.length() - 1);
	    }
	    return result;
	}

	public LinkedList getRoot() {
		return null;
	}

	public String getTableName() {
		return "t_user";
	}

	/**
	 * 用户登陆次数加一
	 */
	public void incLoginNumber() {
		try {
			// 用户登陆次数加一
			this.loginNumber++;
			// 更新数据库
			this.attributes.put("loginnumber", Integer
					.toString(this.loginNumber));
			this.update();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 得到用户的登陆次数
	 */
	public int getLoginNumber() {
		return this.loginNumber;
	}

	/**
	 * 删除
	 */
	public void delete() throws Exception {
		// 系统管理员不能删除。
		if (this.getID().equals("2411803")) {
			return;
		}
		// 从aip_user 表中和自身存储表中删除
		this.deleteFromDB();
		// 从父组织中删除
		Resource parent = this.getParent();
		if (parent != null) {
			getParent().removeChild(this);
		}
		EntityManager.getInstance().remove(this);
		// 记录日志
		LogHelper.logEntity(this.loginUser, "用户维护", "删除用户" + this.getName());
	}

	private void deleteFromDB() throws Exception {
		String id = (String) this.getAttributes().get("id");
		String sql = "delete from aip_user where CUSERID='" + id + "'";
		this.executeSql(sql);
		// 从库中删除
		DBTools.delete(this.getTableName(), getID());
	}

	private void executeSql(String sql) {
		try {
			BSConnection conn = new BSConnection();
			Connection c = conn.getConnection();
			Statement state = c.createStatement();
			state.execute(sql);
			state.close();
			c.close();
		} catch (SQLException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 得到用户所拥有的所有功能
	 */
	public LinkedList getFunctions() {
		return functions;
	}

	public String getName() {
		return (String) attributes.get("name");
	}

	/**
	 * 得到用户所对应的首页模板
	 */
	public String getMainpage() {
		return (String) attributes.get("mainpage");
	}

	/**
	 * 得到本系统的默认密码
	 */
	private String getPass() {
		String result = "000000";
		// 取得默认密码
		String sql = "select f_initpass,f_matchcase from t_setpassrule";
		try {
			String[][] rule = DBTools.executeQueryWithTableHead(sql);
			// 如果有数据
			if (rule.length > 0) {
				result = rule[1][0];
				String matchcase = "区分大小写";
				matchcase = rule[1][1];
				if (matchcase.equals("不区分大小写")) {
					result = result.toUpperCase();
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			System.out.println("未得到默认密码");
		}
		// 加密
		EncryptMachine em = GetEncryptMachineTool.getEncryptMachine();
		result = em.getEncryptData(result, "userpassword");
		return result;
	}

	public String getEName() {
		return (String) attributes.get("ename");
	}

	public void sychronUpdate(Hashtable attributes) {
		super.sychronUpdate(attributes);
		this.setLoginNumber(this.attributes);

	}

	/**
	 * 更新角色列表
	 */
	public void updateRolesList() {
		try {
			this.getAttributes().put("roles", this.getRolesIds());
			this.update();
		} catch (Exception e) {
			throw new RuntimeException("更新用户角色异常", e);
		}
	}

	/**
	 * 设置用户角色
	 */
	public void addRole(Role role) throws Exception {
		// 如果角色列表中不包含该角色,添加,
		if (!this.roles.contains(role)) {
			this.roles.add(role);
		}
	}

	/**
	 * 删除角色
	 */
	public void removeRole(Role role) {
		this.roles.remove(role);
	}

	/**
	 * 得到所有角色id字符串,用,好分割
	 */
	private String getRolesIds() {
		LinkedList temp = Tools.getIds(this.roles);
		return Tools.LinkedListTostring(temp);
	}

	/**
	 * 获取用户相关信息，所有路径，不包含前两层
	 * @return: {
	 * orgs:公司完整汉字路径,
	 * orgids:公司完整id路径,
	 * deps: 部门完整路径,
	 * depids: 部门完整id路径,
	 * names: 自己完整路径,
	 * ids: 自己完整id路径,
	 * dir: 业务逻辑等组建的存放地点
	 * }
	 */
	public JSONObject getInfo() {
		JSONObject result = new JSONObject();
		// 自己的全路径
		result.put("names", ResourceTool.getFullPathName(this, "name", 2));
		result.put("ids", ResourceTool.getFullPathName(this, "id", 2) + ".");
		// 所属公司路径
		BasicResource resource = (BasicResource) this.getParentByType("organization");
		result.put("orgs", ResourceTool.getFullPathName(resource, "name", 2));
		result.put("orgids", ResourceTool.getFullPathName(resource, "id", 2) + ".");
		// 所属部门路径
		resource = (BasicResource) this.getParentByType("department");
		result.put("deps", ResourceTool.getFullPathName(resource, "name", 2));
		result.put("depids", ResourceTool.getFullPathName(resource, "id", 2) + ".");
		// 业务逻辑等存放位置
		resource = (BasicResource) this.getParentHasAttr("f_dir");
		if (resource == null) {
			result.put("dir", "null");
		} else {
			String dir = (String) resource.getAttributes().get("f_dir");
			result.put("dir", dir);
		}

		return result;
	}
}